import { initFullLayer } from '../../utils/LayerUtil';
import ITool from '../ITool';

/**
 * 测量工具箱
 * @implements {ITool}
 */
class MeasureTool extends ITool {
  constructor(_top, _impl) {
    super(_top, _impl);
    this.name = 'MeasureTool';
    this.desc = '测量工具箱';
    this.layeridPrefix = 'MeasureTool';
    // 测距事件绑定
    this._distanceDownHandler = this.distanceDownHandler.bind(this);
    this._distanceMoveHandler = this.distanceMoveHandler.bind(this);
    this._distanceDblclickHandler = this.distanceDblclickHandler.bind(this);
    // 测面积事件绑定
    this._polygonDownHandler = this.polygonDownHandler.bind(this);
    this._polygonMoveHandler = this.polygonMoveHandler.bind(this);
    this._polygonDblclickHandler = this.polygonDblclickHandler.bind(this);
  }

  onAdd() {
    super.onAdd();
    initFullLayer(this);
  }

  onRemove() {
    super.onRemove();
  }

  /**
   * 测距
   */
  distance() {
    this.distancePoints = [];
    this.getMap().doubleClickZoom.disable();
    this.reset();
    this.getMap().on('click', this._distanceDownHandler);
    this.getMap().on('mousemove', this._distanceMoveHandler);
    this.getMap().on('dblclick', this._distanceDblclickHandler);
    this.getUtil('CursorUtil').changeCursor('crosshair');
  }

  /**
   * 计算长度
   * @param {feature} lineString 线坐标
   */
  calcDistance(lineString) {
    return turf.length(lineString).toFixed(2);
  }

  /**
   * 测面积
   */
  area() {
    this.polygonPoints = [];
    this.getMap().doubleClickZoom.disable();
    this.reset();
    this.getMap().on('click', this._polygonDownHandler);
    this.getMap().on('mousemove', this._polygonMoveHandler);
    this.getMap().on('dblclick', this._polygonDblclickHandler);
    this.getUtil('CursorUtil').changeCursor('crosshair');
  }

  /**
   * 计算面积
   * @param {feature} polygon 多边形坐标
   */
  calcArea(polygon) {
    return turf.area(polygon).toFixed(2);
  }

  /**
   * 测距鼠标点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  distanceDownHandler(e) {
    this.distancePoints.push(e.lngLat);
    if (this.distancePoints.length >= 2) {
      this.drawLineString(this.distancePoints, e.lngLat);
    }
  }

  /**
   * 测距鼠标移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  distanceMoveHandler(e) {
    if (this.distancePoints && this.distancePoints.length >= 1) {
      this.drawLineString(this.distancePoints, e.lngLat);
      let distance = this.getLineStringDistance();
      let text = `绘制线段距离为：${distance}km`;
      this.renderTip(e.lngLat, text);
    }
  }

  /**
   * 测距鼠标双击事件
   * @param {*} e 事件参数
   * @ignore
   */
  distanceDblclickHandler(e) {
    // this.drawLineString(this.distancePoints, e.lngLat);
    let distance = this.getLineStringDistance();
    let text = `绘制线段距离为：${distance}km`;
    this.renderTip(e.lngLat, text);
    this.distancePoints = [];
    this.offAll();
    setTimeout(() => {
      this.getMap().doubleClickZoom.enable();
    });
  }

  /**
   * 绘制测距线
   * @param {*} all 所有点
   * @param {*} last 最新点
   * @ignore
   */
  drawLineString(all, last) {
    let before = all[all.length - 1];
    if (before.lng !== last.lng || before.lat !== last.lat) {
      let points = all.concat([last]);
      let coords = points.map((item) => [item.lng, item.lat]);
      let lineString = turf.lineString(coords);
      lineString.properties.sourceType = 'LineString';
      lineString.properties.color = '#ff0000';
      lineString.properties.opacity = 1;
      lineString.properties.width = 3;
      let dots = coords.map((coord) => {
        let point = turf.point(coord);
        point.properties.sourceType = 'Point';
        point.properties.size = 4;
        point.properties.color = '#ff0000';
        point.properties.outlineColor = '#ff0000';
        point.properties.outlineWidth = '1';
        return point;
      });
      let features = [lineString].concat(dots);
      this.getMap().getSource(this._sourceId).setData(turf.featureCollection(features));
    }
  }

  /**
   * 获取测距线长度
   * @ignore
   */
  getLineStringDistance() {
    let lineString = this.getMap().getSource(this._sourceId)._data.features[0];
    return this.calcDistance(lineString);
  }

  /**
   * 测面积鼠标点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonDownHandler(e) {
    this.polygonPoints.push(e.lngLat);
    if (this.polygonPoints.length === 2) {
      this.drawLineString(this.polygonPoints, e.lngLat);
    } else if (this.polygonPoints.length >= 3) {
      this.drawPolygon(this.polygonPoints, e.lngLat);
    }
  }

  /**
   * 测面积鼠标移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonMoveHandler(e) {
    if (this.polygonPoints && this.polygonPoints.length === 1) {
      this.drawLineString(this.polygonPoints, e.lngLat);
      let text = '绘制区域面积为：0㎡';
      this.renderTip(e.lngLat, text);
    } else if (this.polygonPoints && this.polygonPoints.length >= 2) {
      this.drawPolygon(this.polygonPoints, e.lngLat);
      let area = this.getPolygonArea();
      let text = `绘制区域面积为：${area}㎡`;
      this.renderTip(e.lngLat, text);
    }
  }

  /**
   * 测面积鼠标双击事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonDblclickHandler(e) {
    this.drawPolygon(this.polygonPoints, e.lngLat);
    let area = this.getPolygonArea();
    let text = `绘制区域面积为：${area}㎡`;
    this.renderTip(e.lngLat, text);
    this.polygonPoints = [];
    this.offAll();
    setTimeout(() => {
      this.getMap().doubleClickZoom.enable();
    });
  }

  /**
   * 绘制测面积图形
   * @param {*} all 所有点
   * @param {*} last 最新点
   * @ignore
   */
  drawPolygon(all, last) {
    let before = all[all.length - 1];
    if (before.lng !== last.lng || before.lat !== last.lat) {
      let points = all.concat([last]).concat([all[0]]);
      let coords = points.map((item) => [item.lng, item.lat]);
      let polygon = turf.polygon([coords]);
      polygon.properties.sourceType = 'Polygon';
      polygon.properties.color = '#ff0000';
      polygon.properties.opacity = 0.3;
      let dots = coords.map((coord) => {
        let point = turf.point(coord);
        point.properties.sourceType = 'Point';
        point.properties.size = 3;
        point.properties.color = '#ff0000';
        point.properties.outlineColor = '#ff0000';
        point.properties.outlineWidth = '1';
        return point;
      });
      let features = [polygon].concat(dots);
      this.getMap().getSource(this._sourceId).setData(turf.featureCollection(features));
    }
  }

  /**
   * 获取测面积图形面积
   * @ignore
   */
  getPolygonArea() {
    let polygon = this.getMap().getSource(this._sourceId)._data.features[0];
    return this.calcArea(polygon);
  }

  /**
   * 显示提示面板
   * @param {*} position 面板位置
   * @param {*} text 显示内容
   */
  renderTip(position, text) {
    this.removePopup();
    this.popup = new SGMap.Popup({ closeButton: false, offset: [0, -10] });
    this.popup
      .setLngLat(position)
      .setText(text)
      .addTo(this.getMap());
  }

  /**
   * 解除事件绑定
   * @ignore
   */
  offAll() {
    this.getMap().off('click', this._distanceDownHandler);
    this.getMap().off('mousemove', this._distanceMoveHandler);
    this.getMap().off('dblclick', this._distanceDblclickHandler);
    this.getMap().off('click', this._polygonDownHandler);
    this.getMap().off('mousemove', this._polygonMoveHandler);
    this.getMap().off('dblclick', this._polygonDblclickHandler);
    this.getUtil('CursorUtil').reset();
  }

  /**
   * 重置工具
   */
  reset() {
    this.clear();
    this.removePopup();
    this.distancePoints = [];
    this.polygonPoints = [];
    this.offAll();
  }

  /**
   * 清空数据
   * @ignore
   */
  clear() {
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([]));
  }

  /**
   * 隐藏提示面板
   * @ignore
   */
  removePopup() {
    if (this.popup) {
      this.popup.remove();
    }
  }
}

export default MeasureTool;
